import React from 'react';
import { keys, observable, action, computed, set, has, toJS } from 'mobx';
import { SearchPage, SearchAdvanced } from 'weaver-mobile-page';
import {Bubble,Tools} from 'weaver-mobile';

import API from '../../apis/view';
import * as ListApi from '../../apis/list';
import BaseStore from './base';
import {searchToQuery} from "../../util";
import {listParams} from "../../components/list/util";

const getLabel = Tools.getLabel;

const initState = {
  listViewStores: {},
  activeKey: '',
  searchPageStore: null,
  searchAdvancedStore: null,
  searchParams: {},
  showBatch: false,
  showCheck: false,
  newParam: {},
  withSwipeAction: true,
  labelid: '',
  folderid: '',
};

export default class ListStore {

  @observable activeKeyCache = initState.activeKey;
  @observable listViewStores = initState.listViewStores;
  @observable searchPageStore = initState.searchPageStore;
  @observable searchAdvancedStore = initState.searchAdvancedStore;
  @observable searchParams = initState.searchParams;// 搜索参数，用于存储location中的搜索参数、快捷搜索、以及菜单中切换的参数
  locationSearch = '';//location中的search参数
  @observable showBatch = initState.showBatch;
  @observable showCheck = initState.showCheck;
  @observable newParam = initState.newParam;//新建用的param
  
  receiveInterval;//收信定时器
  receivePromise;//收信promise
  @observable unreceiveNum = 0;//未接收邮件数
  @observable errorAccountMap = {};//报错账户

  @observable labelid = initState.labelid; // 标签ID
  @observable folderid = initState.folderid; // 文件ID

  @observable tip = {
    visible: false,
    msg: ''
  };

  constructor() {
    const template = { default: [{ key: 'col', configs: [{ key: 'col_row', configs: [{ key: 'name' }] }] }] };
    this.searchPageStore = new SearchPage.Store({ route: this.path, id: 'searchht', template });
    this.searchAdvancedStore = new SearchAdvanced.Store({ route: this.path, id: 'searchad' });
  }

  @computed get path() {
    return `/${this.activeKey}`;
  }

  @computed get searchHtPath() {
    return `/${this.activeKey}/searchht`;
  }

  @computed get searchAdPath() {
    return `/${this.activeKey}/searchad`;
  }

  @computed get activeKey() {
    return this.activeKeyCache;
  }

  set activeKey(activeKey) {
    this.activeKeyCache = activeKey;
    set(this.searchAdvancedStore, { route: this.path });
    set(this.searchPageStore, { route: this.path });
  }

  @computed get searchKey() {
    if (this.searchAdvancedStore.form) {
      const { quickSearchKey } = this.searchAdvancedStore.form;
      if (quickSearchKey) {
        return quickSearchKey;
      }
    }
    return 'name';
  }

  @action
  setState = (params = {}) => {
    Object.keys(params).forEach(key => {
      this[key] = params[key];
    });
  }

  @action
  clear = () => this.setState(initState)

  @action
  addListStore = (options) => {
    if (!has(this.listViewStores, options.id)) {
      const store = new BaseStore(options);
      set(this.listViewStores, { [store.id]: store });
    }
  }
  
  mergeSearchParams = (searchParams) => {
    this.searchParams = {...this.searchParams, ...searchParams};
  }

  @action
  receiveLetter = () => {
    if (this.receivePromise) return this.receivePromise;
    this.receivePromise = new Promise((resolve) => {
      ListApi.getReceiveAccount({receivemailid: -1}).then((result) => {
        let {accountList} = result;
        if (!Array.isArray(accountList) || accountList.length === 0) {
          this.receivePromise = null;
          return;
        }
        accountList = accountList.filter((account) => !this.errorAccountMap[account.id]);
        if (accountList.length === 0) {
          this.receivePromise = null;
          return;
        }
        Promise.all(accountList.map((account) => {
          return ListApi.receiveEmail({mailAccountId: account.id}).then((result) => {
            return {...result, account};
          });
        })).then((resultArray) => {
          let successNum = 0, errorArray = [];
          resultArray.forEach((res) => {
            if (res.status !== '1' || res.result.receivedMailNumber < 0) {
              this.errorAccountMap[res.account.id] = true;
              errorArray.push(res);
            } else {
              successNum += window.parseInt(res.result.receivedMailNumber, 10);
            }
          });
          this.unreceiveNum += successNum;
          if (errorArray.length > 0) {
            Bubble.error(
              <React.Fragment>
                <div>
                  {getLabel(385607, '邮件接收失败！')}
                  <a onClick={() => Bubble.hide()}>{getLabel(309, '关闭')}</a>
                </div>
                {errorArray.map(errorRes=> (
                  <div>
                    {errorRes.account.accountId}
                    <a
                      onClick={() => {
                        this.setState({tip: {visible: true, msg: errorRes.result.msg.errorString}});
                      }}
                    >
                      {getLabel(83110, '查看详情')}
                    </a>
                  </div>
                ))}
              </React.Fragment>
            , 0);
          }
          this.receivePromise = null;
        });
      });
      resolve();
    });
  }
  
  @action
  initReceiveLetterInterval = () => {
    this.clearReceiveLetterInterval();
    this.receiveInterval = window.setInterval(this.receiveLetter, 60 * 1000);
  }
  
  @action
  clearReceiveLetterInterval = () => {
    if (this.receiveInterval) {
      window.clearInterval(this.receiveInterval);
    }
  }
  
  @action
  getListStore = () => {
    if (!this.activeKey || keys(this.listViewStores).length === 0) return null;
    return this.listViewStores[this.activeKey];
  }
  
  // search
  onSearch = (params) => {
    const { activeKey, searchParams, searchKey } = this;
    const list = this.getListStore();
    if (list) {
      params = {...this.getParams(), ...params};
      if (activeKey !== 'tag' && params.menu_labelid) {
        delete params.menu_labelid;
        delete params.labelid;
      }
      if (activeKey === 'inbox') {
        params = {...params, menu_folderid: 0}
      } 
      if (activeKey === 'tag' && !params.menu_labelid) {
        if (params.menu_folderid) delete params.menu_folderid
        params = {...params, menu_labelid: this.labelid, labelid: this.labelid}
      } 
      if (activeKey === 'folder' && !params.folderid) {
        params = {...params, folderid: this.folderid, menu_folderid: this.folderid}
      }
      if ((activeKey === 'star' || activeKey === 'inner' || activeKey === 'doing') && params.folderid) {
        delete params.menu_folderid;
        delete params.folderid;
      }
      list.getData({
        url: '/api/email/list/allList',
        params,
      });
      if (activeKey === 'inbox' && params.current === 1) {
        this.unreceiveNum = 0;
      }
    }
    const currentValue = searchParams[searchKey] || '';
    if (activeKey && currentValue) {
      const key = `emailSearchHistory__${activeKey}`;
      let searchHistory = localStorage.getItem(key);
      searchHistory = searchHistory ? JSON.parse(searchHistory) : [];
      searchHistory = searchHistory.filter(h => h.key !== currentValue);
      searchHistory.unshift({ key: currentValue, name: currentValue });
      localStorage.setItem(key, JSON.stringify(searchHistory));
    }
  }

  getParams = (search = this.locationSearch) => {
    const list = this.getListStore();
    if (!list) return {};
    const { activeKey, searchParams, searchAdvancedStore: { form } } = this;
    const { current } = list;
    const params = {
      ...searchParams,
      ...searchToQuery(search),//页面上链接过来的搜索条件，可以被form表单修改
      ...(form ? form.formParams : {}),//表单中的搜索条件
      ...listParams[activeKey],//收件箱、发件箱等的搜索条件，除链接调整外不会被改变。
      current,
      pageSize: 20,
    };
    return params;
  }

  @action
  setStar = (params) => {
    this.withSwipeAction = false;
    API.setStar(params).then(res => {
      this.updateListData(params.mailIds, {starred: params.star});
    })
  }

  @action 
  deleteEmail = async (params) => {
    let res = await API.deleteEmail(params)
    return res
  }

  @action // 设为完成
  completeWaitdeal = (params) => {
    API.completeWaitdeal(params).then(res => {
      if (res.status === '1') {
        Bubble.success(getLabel(16746, '设置成功！'))
      }
      if (this.activeKey === "doing") { // 待办邮件列表，直接删除
        this.updateListData(params.mailIds, {}, true);
      } else {
        this.updateListData(params.mailIds, { mailIds: 0, waitdeal: 0, waitdealBean: {} });
      }
    });
  }

  @action // 移动到
  operateUserMailFolder = async (params) => {
    let res = await API.operateUserMailFolder(params)
    return res
  }

  @action // 标记为
  markEmailToByMobile = (params, callback) => {
    API.markEmailToByMobile(params).then(res => {
      const arr = JSON.parse(params.markArray);
      let resParams = {};
      arr.map(v => {
        if (v.key === 'markAsReaded') {
          resParams = { ...resParams, status: 1 };
        } else if (v.key === 'markAsUnread') {
          resParams = { ...resParams, status: 0 };
        } else if (v.key === 'markAsStart') {
          resParams = { ...resParams, starred: 1 };
        } else if (v.key === 'markAsCancelStar') {
          resParams = { ...resParams, starred: 0 };
        } else if (v.key === 'markAllAsReaded') {
          resParams = { ...resParams, status: 1  };
        }
        return null;
      });
      res.labels && (resParams = { ...resParams, labels: res.labels });
      this.updateListData(arr[0] && arr[0].mailIds, resParams,);
      if (callback) callback();
    })
  }

  // 更新list数据
  updateListData = (ids, params, isDelete = false) => {
    const list = this.getListStore();
    const { listViewStore: { data, updateDataSource, setState } } = list;
    let curData = [];
    if (isDelete) {
      curData = toJS(data).filter(v => ids.split(',').indexOf(v.id) < 0);
    } else {
      curData = toJS(data).map(v => {
        if (ids.split(',').indexOf(v.id) > -1) {
          return {
            ...v,
            ...params,
          }
        }
        return v;
      });
    }
    Promise.all([setState({ data: curData})]).then(action(() => {
      this.showCheck = false;
      setState({ selectedRowKeys: [] });
      updateDataSource();
      this.withSwipeAction = true;
    }));
  }

  @action
  updateListState = () => {
    const list = this.getListStore();
    const { listViewStore: { setState } } = list;
    this.showCheck = false;
    setState({ selectedRowKeys: [] });
    this.withSwipeAction = true;
  }
}